package com.lw.common.utils

import android.os.Parcelable
import com.lw.common.Constants
import com.tencent.mmkv.MMKV
import java.util.*

/**
 * @description: MMKV 腾讯出品 替代SharedPreferences 是基于 mmap 内存映射的 key-value 组件，底层序列化/反序列化
 * 使用protobuf实现，性能高，稳定性强。从 2015年中至今在微信上使用，其性能和稳定性经过了时间的验证
 * @author: yuan
 * @date: 2023/3/2/0002
 */
object MMKVUtils {
    var mmkv: MMKV? = null

    init {
        mmkv = MMKV.defaultMMKV()
    }

    fun put(key: String, value: Any?): Boolean {
        return when (value) {
            is String -> mmkv?.encode(key, value)!!
            is Float -> mmkv?.encode(key, value)!!
            is Boolean -> mmkv?.encode(key, value)!!
            is Int -> mmkv?.encode(key, value)!!
            is Long -> mmkv?.encode(key, value)!!
            is Double -> mmkv?.encode(key, value)!!
            is ByteArray -> mmkv?.encode(key, value)!!
            else -> false
        }
    }

    /**
     * 这里使用安卓自带的Parcelable序列化，它比java支持的Serializer序列化性能好些
     */
    fun <T : Parcelable> put(key: String, t: T?): Boolean {
        if (t == null) {
            return false
        }
        return mmkv?.encode(key, t)!!
    }

    /**
     * 保存数据
     */
    fun put(key: String, sets: Set<String>?): Boolean {
        if (sets == null) {
            return false
        }
        return mmkv?.encode(key, sets)!!
    }

    /**
     * 获取已保存数据
     */
    fun getInt(key: String): Int? {
        return mmkv?.decodeInt(key, 0)
    }

    fun getDouble(key: String): Double? {
        return mmkv?.decodeDouble(key, 0.00)
    }

    fun getLong(key: String): Long? {
        return mmkv?.decodeLong(key, 0L)
    }

    fun getBoolean(key: String): Boolean {
        return mmkv?.decodeBool(key, false) == true
    }

    fun getFloat(key: String): Float? {
        return mmkv?.decodeFloat(key, 0F)
    }

    fun getByteArray(key: String): ByteArray? {
        return mmkv?.decodeBytes(key)
    }

    fun getString(key: String): String {
        return mmkv?.decodeString(key, "").toString()
    }

    /**
     * SpUtils.getParcelable<Class>("")
     */
    inline fun <reified T : Parcelable> getParcelable(key: String): T? {
        return mmkv?.decodeParcelable(key, T::class.java)
    }

    fun getStringSet(key: String): Set<String>? {
        return mmkv?.decodeStringSet(key, Collections.emptySet())
    }

    /**
     * 根据key移除已保存数据
     */
    fun removeKey(key: String) {
        mmkv?.removeValueForKey(key)
    }

    /**
     * 移除所有数据
     */
    fun clearAll() {
        mmkv?.clearAll()
    }

    /**
     * 获取token
     */
    fun getToken(): String {
        return getString(Constants.KEY_TOKEN).ifEmpty { getString(Constants.KEY_TOKEN) }
    }

    /**
     * 获取baseUrl
     */
    fun getBaseUrl(): String {
        return getString(Constants.BASE_URL)
    }
}